import random
import string
import time
import email
import re
from django.urls import reverse
from django.shortcuts import render, redirect
from django.contrib import auth
from django.core.cache import cache
from django.contrib.auth.models import User
from django.http import JsonResponse

from .forms import LoginForm, RegForm, NickNameForm, EmailForm, ResetPasswordForm, RetrievePasswordForm
from .models import Profile
from .utils import send_activation_email, send_captcha_email

def login(request):
    if request.method == 'POST':
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            user = login_form.cleaned_data['user']
            auth.login(request, user)
            return redirect(request.GET.get('from', reverse('home')))
    elif request.method == 'GET':
        login_form = LoginForm()
    context = {}
    context['login_form'] = login_form
    return render(request, 'user/login.html', context)

def modal_login(request):
    '''
    服务于ajax异步登录
    '''
    data = {}
    login_form = LoginForm(request.POST)
    if login_form.is_valid():
        user= login_form.cleaned_data['user']
        auth.login(request, user)
        data['status'] = 'SUCCESS'
    else:
        # 用户名和密码不匹配
        data['status'] = 'ERROR'
        message = login_form.errors.as_text().split('\n')
        data['message'] = '\n'.join([message[i] for i in range(len(message)) if i%2==1])
    return JsonResponse(data)

def register(request):
    context = {}
    if request.method == 'POST':
        reg_form = RegForm(request.POST)
        if reg_form.is_valid():
            # 新建用户，暂时不绑定邮箱
            username = reg_form.cleaned_data['username']
            email = reg_form.cleaned_data['email']
            password = reg_form.cleaned_data['password']
            user = User.objects.create_user(username, password=password)
            # 因为邮箱还未验证，因此是未激活的状态
            user.is_active = False
            user.save()
            # 新建后发送验证邮件
            data = send_activation_email(request, user, email)
            if data['status'] == 'SUCCESS':
                # 返回跳转连接
                context['email'] = email
                context['redirect_to'] = request.GET.get('from', reverse('home'))
                return render(request, 'user/register_info.html', context)
            else:
                reg_form.add_error(None, data['message'])
    elif request.method == 'GET':
        reg_form = RegForm()
    context['reg_form'] = reg_form
    return render(request, 'user/register.html', context)

def logout(request):
    user = request.user
    if user.is_authenticated:
        auth.logout(request)
    return redirect(request.GET.get('from', reverse('home')))

def user_info(request):
    context = {}
    return render(request, 'user/user_info.html', context)

def change_nickname(request):
    redirect_url = request.GET.get('from', reverse('home'))
    if request.method == 'POST':
        nickname_form = NickNameForm(request.POST, user=request.user)
        if nickname_form.is_valid():
            user = nickname_form.cleaned_data['user']
            new_nickname = nickname_form.cleaned_data['new_nickname']
            profile, created = Profile.objects.get_or_create(user=user)
            profile.nickname = new_nickname
            profile.save()
            return redirect(redirect_url)
    elif request.method == 'GET':
        context = {}
        nickname_form = NickNameForm()
        context['form'] = nickname_form
        context['form_title'] = '修改昵称'
        context['btn_text'] = '修改'
        context['redirect_url'] = redirect_url
        return render(request, 'form.html', context)

def bind_email(request):
    if request.method == 'POST':
        data = {}
        email_form = EmailForm(request.POST, user=request.user)
        if email_form.is_valid():
            # 表单验证通过，获取数据
            user = email_form.cleaned_data['user']
            email = email_form.cleaned_data['email']
            # 发送邮件
            data = send_activation_email(request, user, email)
            return JsonResponse(data)
        else:
            data['status'] = 'ERROR'
            errors =  email_form.errors
            data['message'] = '\n'.join([errors[i] for i in range(len(errors)) if i%2 == 1])
            return JsonResponse(data)
    elif request.method == 'GET':
        email_form = EmailForm()
        context = {}
        context['form'] = email_form
        context['form_title'] = '绑定邮箱'
        context['btn_text'] = '发送验证码'
        context['redirect_url'] = ''
        return render(request, 'user/bind_email.html', context)
    
def activate_user(request, captcha, user_pk):
    '''
    通过激活邮件激活账户，绑定邮箱
    '''
    context = {}
    cache_key = 'activation_{}'.format(user_pk)
    verify_context = cache.get(cache_key)
    if verify_context is None:
        context['status'] = False
        context['message'] = '验证链接无效'
    # 获取到了cache，先判断用户是否存在
    elif not User.objects.filter(pk=user_pk).exists():
        context['status'] = False
        context['message'] = '用户异常'
    # 判断验证码是否匹配 
    elif captcha != verify_context['captcha']:
        context['status'] = False
        context['message'] = '验证连接错误'
    else:
        # 激活用户并直接登录
        user = User.objects.get(pk=user_pk)
        user.email = verify_context['email']
        user.is_active = True
        user.save()
        auth.login(request, user)
        context['status'] = True
        context['action_username'] = user.username
        context['action_info'] = '您已经通过邮箱激活了您的账号，即将为您导航到首页'
        context['redirect_url'] = reverse('home')
        # 清理掉cache
        print('clear cache {}'.format(cache_key))
        cache.delete(cache_key)
    return render(request, 'user/action_finish.html', context)

def reset_password(request):
    '''
    重置密码，已知当前密码
    '''
    redirect_url = request.GET.get('from', reverse('home'))
    context = {}
    if request.method == 'POST':
        reset_password_form = ResetPasswordForm(request.POST, user=request.user)
        if reset_password_form.is_valid():
            new_password = reset_password_form.cleaned_data['new_password']
            user = reset_password_form.cleaned_data['user']
            user.set_password(new_password)
            user.save()
            # 跳转到登录界面
            return redirect(reverse('login') + '?from=' + redirect_url)
    elif request.method == 'GET':
        reset_password_form = ResetPasswordForm()
    context['form'] = reset_password_form
    context['form_title'] = '重置密码'
    context['btn_text'] = '修改'
    context['redirect_url'] = redirect_url
    return render(request, 'form.html', context)

def retrieve_password(request):
    redirect_url = request.GET.get('from', reverse('home'))
    if request.method == 'POST':
        retrieve_password_form = RetrievePasswordForm(request.POST)
        if retrieve_password_form.is_valid():
            new_password = retrieve_password_form.cleaned_data['new_password']
            user = retrieve_password_form.cleaned_data['user']
            user.set_password(new_password)
            user.save()
            # 清理数据库缓存
            cache.delete(retrieve_password_form.cleaned_data['cache_key'])
            context = {}
            context['status'] = True
            context['action_username'] = user.username
            context['action_info'] = '您的密码已经修改成功，即将为您跳转到登陆页面'
            context['redirect_url'] = reverse('login') + '?from=' + redirect_url
            return render(request, 'user/action_finish.html', context)
    elif request.method == 'GET':
        retrieve_password_form = RetrievePasswordForm()
    context = {}
    context['form'] = retrieve_password_form
    context['form_title'] = '找回密码'
    context['btn_text'] = '确认'
    context['redirect_url'] = redirect_url
    return render(request, 'user/retrieve_password.html', context)

def send_captcha(request):
    '''
    发送找回密码的验证码
    '''
    data = {}
    cache_prefix = request.GET.get('cache_prefix')
    email = request.GET.get('email')
    m = re.match(r'^[0-9a-zA-Z_-]+@[0-9a-zA-Z_-]+(\.[0-9a-zA-Z_-]+)+$', email)
    if m is None:
        data['status'] = 'ERROR'
        data['message'] = '邮箱格式错误'
        return JsonResponse(data)
    if not User.objects.filter(email=email).exists():
        data['status'] = 'ERROR'
        data['message'] = '该邮箱未被注册'
        return JsonResponse(data)
    user = User.objects.get(email=email)
    data = send_captcha_email(user, email, cache_prefix)
    return JsonResponse(data)
